package com.apanal.qlife.common.resolver;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.apanal.qlife.common.aop.SysLogAspect;
import com.apanal.qlife.common.constants.Constants;
import com.apanal.qlife.common.exception.BusinessException;
import com.apanal.qlife.common.util.WebUtils;

/**
 * 全局异常解析器
 * 
 * 
 * @author shuliangxing
 * 
 * @date 2015-3-20下午5:50:29
 */
public class CommonExceptionResolver implements HandlerExceptionResolver {

	private static final Logger logger = Logger
			.getLogger(CommonExceptionResolver.class);

	@Override
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {

		// 日志分组,方便查看多个日志嵌套的情况
		Long logGroup = (Long) request.getAttribute(SysLogAspect.LOG_GROUP_ID);
		if (logGroup == null) {
			logger.error("=====service error======", ex);
		} else {
			logger.error("=====service error====== 错误代码：" + logGroup, ex);
		}

		// // 异常的堆栈信息字符串
		// String stackTraceStr = ExceptionUtil.getStackTrace(ex);
		// // 适当减少堆栈信息长度
		// if (stackTraceStr != null && stackTraceStr.length() > 3000) {
		// stackTraceStr = stackTraceStr.substring(0, 3000) + " 省略...";
		// }

		// 默认异常提示
		String message = Constants.DEFAULT_MSG_ERROR;
		if (logGroup != null) {
			message += " 错误代码：" + logGroup;
		}
		// 如果是业务异常,返回业务异常提示
		if (ex instanceof BusinessException) {
			message = ex.getMessage();
		} else if (ex instanceof UnauthorizedException) {
			message = Constants.DEFAULT_MSG_UNAUTHORIZED;
		}

		// 如果是异步请求(Ajax),设置500状态并返回错误提示信息
		if (WebUtils.isAjaxRequest(request)) {
			response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
			// ajax请求失败时隐式显示错误信息
			try {
				// WebUtils.sendData(message + "<div style='display: none;'>"
				// + stackTraceStr + "</div>", response);
				WebUtils.sendData(message, response);
			} catch (IOException e) {
				logger.error("service io error", e);
			}
			return new ModelAndView();
		}
		// 如果是同步请求即普通请求,返回到错误页面
		else {
			// 没有权限访问
			if (ex instanceof UnauthorizedException) {
				// return new ModelAndView("sys/unauthorized",
				// Constants.DEFAULT_EXCEPTION, ex.getMessage());
				return new ModelAndView("sys/unauthorized");
			} else {
				// return new ModelAndView(Constants.PC_EXCEPTION,
				// Constants.DEFAULT_EXCEPTION, stackTraceStr);
				return null;
			}
		}
	}

}
